﻿
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System;

namespace BaseUtils.Utils
{
    public class IniHelper
    {
        private string DefaultSection = "curm";
        //[System.Runtime.InteropServices.DllImport("user32.dll")]
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        //[System.Runtime.InteropServices.DllImport("user32.dll")]
        [DllImport("kernel32")]
        private static extern long GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
        //[System.Runtime.InteropServices.DllImport("user32.dll")]
        [DllImport("kernel32")]
        private static extern long GetPrivateProfileStringA(string section, string key, string def, Byte[] retVal, int size, string filePath);


        private static readonly Dictionary<Type, Func<string, object>> Converters =
            new Dictionary<Type, Func<string, object>>
            {
                { typeof(string), s => s },
                { typeof(int), s => int.Parse(s) },
                { typeof(float), s => float.Parse(s) },
                { typeof(bool), s => bool.Parse(s) },
                { typeof(decimal), s => decimal.Parse(s) },
                { typeof(DateTime), s => DateTime.Parse(s) },
            };

        private string sPath = null;
        public IniHelper(string path = null)
        {
            if (path == null)
            {
                path = AppDomain.CurrentDomain.BaseDirectory + "\\NW_CONFIG.ini";
            }
            this.sPath = path;
        }
        /// <summary>
        /// 写入某节某值
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public void WriteValue(string section, string key, string val)
        {
            WritePrivateProfileString(section, key, val, sPath);
        }

        public void WriteValue(string key, string val)
        {
            WriteValue(DefaultSection, key, val);
        }

        /// <summary>
        /// 读取某节某值
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string ReadValue(string section, string key)
        {
            StringBuilder temp = new StringBuilder(2048);
            GetPrivateProfileString(section, key, "", temp, 2048, sPath);
            return temp.ToString();
        }

        public string ReadValue(string key)
        {
            return ReadValue(DefaultSection, key);
        }
        public T ReadValue<T>(string key)
        {
            string v = ReadValue(DefaultSection, key);
            if (string.IsNullOrEmpty(v))
            {
                return (T)default;
            }
            Converters.TryGetValue(typeof(T), out var func);
            return (T)func(v);
        }
        /// <summary>
        /// 读取所有的节
        /// </summary>
        /// <returns></returns>
        public List<string> ReadSections()
        {
            return ReadSections(sPath);
        }
        public List<string> ReadSections(string iniFilename)
        {
            List<string> sections = new List<string>();
            byte[] buf = new byte[65536];
            long len = GetPrivateProfileStringA(null, null, null, buf, buf.Length, iniFilename);
            int j = 0;
            for (int i = 0; i < len; i++)
            {
                if (buf[i] == 0)
                {
                    sections.Add(Encoding.Default.GetString(buf, j, i - j));
                    j = i + 1;
                }
            }
            return sections;
        }
        /// <summary>
        /// 读取所有的值
        /// </summary>
        /// <param name="section"></param>
        /// <returns></returns>
        public List<string> ReadKeys(string section)
        {
            return ReadKeys(section, sPath);
        }
        public List<string> ReadKeys(string SectionName, string iniFileName)
        {
            List<string> keys = new List<string>();
            byte[] buf = new byte[65536];
            long len = GetPrivateProfileStringA(SectionName, null, null, buf, buf.Length, iniFileName);
            int j = 0;
            for (int i = 0; i < len; i++)
            {
                if (buf[i] == 0)
                {
                    keys.Add(Encoding.Default.GetString(buf, j, i - j));
                    j = i + 1;
                }
            }
            return keys;
        }
        /// <summary>
        /// 删除某节
        /// </summary>
        /// <param name="section"></param>
        public void DeleteSection(string section)
        {
            WritePrivateProfileString(section, null, null, sPath);
        }
        /// <summary>
        /// 删除某值
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        public void DeleteKey(string section, string key)
        {
            WritePrivateProfileString(section, key, null, sPath);
        }
        //static RoboticsINI.RoboticsINI Ini = new RoboticsINI.RoboticsINI();

        //static object mainLock1 = new object();

        //static object mainLock2 = new object();

        ///// <summary>
        /////         string user = IniHelper.IniReadValue("NetworkCredential", "user", Application.StartupPath + @"\MESCFG.ini");
        ///// </summary>
        ///// <param name="Section"></param>
        ///// <param name="Key"></param>
        ///// <param name="Inipath"></param>
        ///// <returns></returns>
        //public static string IniReadValue(string Section, string Key, string Inipath)
        //{
        //    lock (mainLock1)
        //    {
        //        string str = Ini.IniReadValue(Section, Key, Inipath);
        //        return str;
        //    }
        //}

        //public static void IniWriteValue(string Section, string Key, string Val, string Inipath)
        //{
        //    lock (mainLock2)
        //    {
        //        Ini.IniWriteValue(Section, Key, Val, Inipath);
        //    }
        //}
    }
}
